﻿namespace Snoop.Infrastructure.Diagnostics.Providers;

using System.Collections.Generic;
using System.Reflection;
using System.Windows.Controls;
using Snoop.Data.Tree;

public class NonVirtualizedListsDiagnosticProvider : DiagnosticProvider
{
    private static readonly PropertyInfo? itemsHostPropertyInfo = typeof(ItemsControl).GetProperty("ItemsHost", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);

    private const int Threshold = 50;

    public override string Name => "Non virtualized long lists";

    public override string Description => $"Warns if an ItemsControl with more than {Threshold} items is not virtualized.";

    protected override IEnumerable<DiagnosticItem> GetDiagnosticItemsInternal(TreeItem treeItem)
    {
        if (treeItem.Target is not ItemsControl itemsControl
            || itemsHostPropertyInfo is null)
        {
            yield break;
        }

        if (itemsControl.Items.Count <= Threshold)
        {
            yield break;
        }

        var panel = itemsHostPropertyInfo.GetValue(itemsControl, null);

        if (panel is not null
            && panel is not VirtualizingPanel)
        {
            yield return
                new(this,
                    "Virtualize ItemsControl",
                    $"ItemsControl with {itemsControl.Items.Count} items should be virtualized.",
                    DiagnosticArea.Performance,
                    DiagnosticLevel.Warning)
                {
                    TreeItem = treeItem,
                    Dispatcher = itemsControl.Dispatcher,
                    SourceObject = itemsControl
                };
        }
    }
}